import router from './index';
import store from '@/store';
import NProgress from 'nprogress';
import 'nprogress/nprogress.css';
import Layout from '@/layout/Layout.vue';
import storeUtils from '@/utils/storeUtils';

NProgress.configure({showSpinner: false});

const whiteList = ['/login'];
router.beforeEach((to, from, next) => {
    NProgress.start();
    store.commit('SET_BROWSER_HEADER_TITLE', to.name);
    if (to.query.token) {
        store.dispatch("setToken", to.query.token).then((response: any) => {
            console.log(response)
        });
        delete to.query.token;
    }
    if (!store.getters.projectInfo || store.getters.projectInfo.default) {
        store.dispatch('setProjectInfo').then((response: any) => {
            console.log(response)
        });
    }

    if (store.getters.token) {
        /* has token*/
        if (to.path === '/login') {
            next({path: '/'});
        } else {
            if (store.getters.routers.length === 0) {
                // 判断当前用户是否已拉取完user_info信息
                store.dispatch('GetInfo').then((res: any) => {
                    // 根据roles权限生成可访问的路由表
                    routerGo(to, next);
                }).catch((err: any) => {
                    store.dispatch('FedLogOut').then(() => {
                        next({path: '/'});
                    });
                });
            } else {
                next();
            }
        }
    } else {
        // 没有token
        if (whiteList.indexOf(to.path) !== -1) {
            // 在免登录白名单，直接进入
            next();
        } else {
            storeUtils.clearStore();
            // if (store.getters.routers || store.getters.token) {
            //     location.reload(); // 为了重新实例化vue-router对象 避免bug
            // }
            next(`/login?redirect=${to.path}`); // 否则全部重定向到登录页
            NProgress.done();
        }
    }
});

router.afterEach(() => {
    NProgress.done();
    setTimeout(() => {
        setTitle(store.getters.browserHeaderTitle);
    }, 10);
});


/**
 * 动态注册路由
 * @param to
 * @param next
 */
function routerGo(to: any, next: any) {
    const routers = store.getters.addRoutes;
    const getRouter = filterAsyncRouter(routers); // 过滤路由
    getRouter.push({
        path: '*',
        hidden: true,
        redirect: '/404',
    });
    router.addRoutes(getRouter); // 动态添加路由
    next({...to, replace: true});
}

/**
 * 过滤处理路由
 * @param asyncRouterMap
 * @returns {*}
 */
// 遍历后台传来的路由字符串，转换为组件对象
function filterAsyncRouter(asyncRouterMap: any) {
    const jobLog = {
        path: 'job/log',
        visible: true,
        name: '任务日志',
        component: "JobLog",
        meta: {
            title: '任务日志',
            icon: ''
        }
    };
    const editTable = {
        path: 'gen/edit/:tableId(\\d+)',
        visible: true,
        name: '修改生成配置',
        component: "EditTable",
        meta: {
            title: '修改生成配置',
            icon: ''
        }
    };
    return asyncRouterMap.filter((route: any) => {
        if (route.path === "/monitor") {
            if (!route.children) {
                route.children = [];
            }
            route.children.push(jobLog)
        }
        if (route.path === "/tool") {
            if (!route.children) {
                route.children = [];
            }
            route.children.push(editTable)
        }
        if (route.component) {
            // Layout组件特殊处理
            if (route.component === 'Layout') {
                route.component = Layout;
            } else {
                route.meta.cache = true;
                route.component = loadView(route.component);
            }
        }
        if (route.children != null && route.children && route.children.length) {
            route.children = filterAsyncRouter(route.children);
        }
        return true;
    });
}


export const loadView = (view: any) => { // 路由懒加载
    return () => import(`@/views/${view}`);
};

/**
 * 设置浏览器头部标题
 */
function setTitle(title: string): void {
    title = title ? `${store.getters.projectInfo.name}  ${title}` : store.getters.projectInfo.name;
    window.document.title = title;
}
